const multer = require('multer');
const sharp = require('sharp');
const path = require('path');
const fs = require('fs').promises;

/**
 * 文件上传服务类
 * 负责处理文件上传、图片压缩、文件管理等功能
 */
class UploadService {
  constructor() {
    this.uploadDir = path.join(__dirname, '../public');
    this.maxFileSize = 5 * 1024 * 1024; // 5MB
    this.allowedImageTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
    this.allowedDocTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
    
    this.init();
  }

  /**
   * 初始化上传服务
   */
  async init() {
    try {
      // 确保必要的目录存在
      await this.ensureDirectories();
      console.log('✅ 文件上传服务初始化成功');
    } catch (error) {
      console.error('❌ 文件上传服务初始化失败:', error);
    }
  }

  /**
   * 确保必要的目录存在
   */
  async ensureDirectories() {
    const dirs = [
      'images/hospitals/logos',
      'images/hospitals/posters',
      'images/departments/logos',
      'images/doctors/photos',
      'images/common',
      'files/reports',
      'files/exports',
      'uploads/temp',
      'uploads/permanent'
    ];

    for (const dir of dirs) {
      const fullPath = path.join(this.uploadDir, dir);
      try {
        await fs.mkdir(fullPath, { recursive: true });
      } catch (error) {
        if (error.code !== 'EEXIST') {
          throw error;
        }
      }
    }
  }

  /**
   * 配置multer存储
   */
  getStorageConfig(type = 'image') {
    const storage = multer.diskStorage({
      destination: (req, file, cb) => {
        const uploadPath = this.getUploadPath(type, req.body.category);
        cb(null, uploadPath);
      },
      filename: (req, file, cb) => {
        const uniqueName = this.generateFileName(file.originalname, req.body.prefix);
        cb(null, uniqueName);
      }
    });

    return multer({
      storage,
      limits: {
        fileSize: this.maxFileSize
      },
      fileFilter: (req, file, cb) => {
        if (type === 'image') {
          if (this.allowedImageTypes.includes(file.mimetype)) {
            cb(null, true);
          } else {
            cb(new Error('只支持 JPG、PNG、GIF 格式的图片文件'), false);
          }
        } else if (type === 'document') {
          if (this.allowedDocTypes.includes(file.mimetype)) {
            cb(null, true);
          } else {
            cb(new Error('只支持 PDF、DOC、DOCX 格式的文档文件'), false);
          }
        } else {
          cb(null, true);
        }
      }
    });
  }

  /**
   * 获取上传路径
   */
  getUploadPath(type, category) {
    const basePath = path.join(this.uploadDir);
    
    switch (type) {
      case 'image':
        switch (category) {
          case 'hospital_logo':
            return path.join(basePath, 'images/hospitals/logos');
          case 'hospital_poster':
            return path.join(basePath, 'images/hospitals/posters');
          case 'department_logo':
            return path.join(basePath, 'images/departments/logos');
          case 'doctor_photo':
            return path.join(basePath, 'images/doctors/photos');
          default:
            return path.join(basePath, 'images/common');
        }
      case 'document':
        return path.join(basePath, 'files/reports');
      default:
        return path.join(basePath, 'uploads/temp');
    }
  }

  /**
   * 生成唯一文件名
   */
  generateFileName(originalName, prefix = '') {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    const ext = path.extname(originalName).toLowerCase();
    const name = path.basename(originalName, ext).replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '_');
    
    return `${prefix ? prefix + '_' : ''}${name}_${timestamp}_${random}${ext}`;
  }

  /**
   * 压缩图片
   */
  async compressImage(inputPath, outputPath, options = {}) {
    try {
      const {
        width = 800,
        height = 600,
        quality = 80,
        format = 'jpeg'
      } = options;

      await sharp(inputPath)
        .resize(width, height, { 
          fit: 'inside',
          withoutEnlargement: true 
        })
        .jpeg({ quality })
        .toFile(outputPath);

      return outputPath;
    } catch (error) {
      console.error('图片压缩失败:', error);
      throw error;
    }
  }

  /**
   * 生成缩略图
   */
  async generateThumbnail(inputPath, outputPath, size = 200) {
    try {
      await sharp(inputPath)
        .resize(size, size, { 
          fit: 'cover',
          position: 'center'
        })
        .jpeg({ quality: 70 })
        .toFile(outputPath);

      return outputPath;
    } catch (error) {
      console.error('缩略图生成失败:', error);
      throw error;
    }
  }

  /**
   * 删除文件
   */
  async deleteFile(filePath) {
    try {
      const fullPath = path.join(this.uploadDir, filePath);
      await fs.unlink(fullPath);
      return true;
    } catch (error) {
      console.error('删除文件失败:', error);
      return false;
    }
  }

  /**
   * 获取文件信息
   */
  async getFileInfo(filePath) {
    try {
      const fullPath = path.join(this.uploadDir, filePath);
      const stats = await fs.stat(fullPath);
      
      return {
        size: stats.size,
        created: stats.birthtime,
        modified: stats.mtime,
        isFile: stats.isFile(),
        isDirectory: stats.isDirectory()
      };
    } catch (error) {
      console.error('获取文件信息失败:', error);
      return null;
    }
  }

  /**
   * 清理临时文件
   */
  async cleanupTempFiles() {
    try {
      const tempDir = path.join(this.uploadDir, 'uploads/temp');
      const files = await fs.readdir(tempDir);
      const now = Date.now();
      const maxAge = 24 * 60 * 60 * 1000; // 24小时

      let cleanedCount = 0;

      for (const file of files) {
        const filePath = path.join(tempDir, file);
        const stats = await fs.stat(filePath);
        
        if (now - stats.mtime.getTime() > maxAge) {
          await fs.unlink(filePath);
          cleanedCount++;
        }
      }

      console.log(`🧹 清理了 ${cleanedCount} 个临时文件`);
      return cleanedCount;
    } catch (error) {
      console.error('清理临时文件失败:', error);
      return 0;
    }
  }

  /**
   * 获取文件URL
   */
  getFileUrl(filePath) {
    if (!filePath) return null;
    
    // 移除开头的 public/ 或 ./public/
    const cleanPath = filePath.replace(/^\.?\/?public\//, '');
    return `/static/${cleanPath}`;
  }

  /**
   * 验证文件类型
   */
  validateFileType(file, allowedTypes) {
    return allowedTypes.includes(file.mimetype);
  }

  /**
   * 获取文件扩展名
   */
  getFileExtension(filename) {
    return path.extname(filename).toLowerCase();
  }

  /**
   * 检查文件是否存在
   */
  async fileExists(filePath) {
    try {
      const fullPath = path.join(this.uploadDir, filePath);
      await fs.access(fullPath);
      return true;
    } catch (error) {
      return false;
    }
  }
}

module.exports = new UploadService();
